package com.syjy.tunnelworker;

import ch.qos.logback.classic.Logger;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.syjy.DataExchangeException;
import com.syjy.TunnelLoggerFactory;
import com.syjy.container.ProtocolTunnelContainer;
import com.syjy.tunnelinfo.BaseTunnelInfo;
import com.syjy.tunnelinfo.TunnelStatus;
import com.syjy.tunnelinfo.TunnelType;
import lombok.Getter;
import lombok.Setter;
import wei.yigulu.netty.BaseProtocolBuilder;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * 通道信息的抽象类，用以实时储存、管理、改变、查询通道的状态
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
@Getter
@Setter
public abstract class BaseProtocolTunnel<T extends BaseTunnelInfo,E extends BaseProtocolBuilder> {


	protected Logger log;


	protected E protocolBuilder;
	/**
	 * 该通道的信息及其负责采集的点位
	 */
	@JSONField(serialize = false)
	protected T tunnelInfo;
	/**
	 * 通道的ID
	 */
	protected String tunnelId;
	/**
	 * 通道的类型
	 */
	protected TunnelType tunnelType;
	/**
	 * 连接接信息
	 */
	@JSONField(serialize = false)
	protected List<InetSocketAddress> connectors;
	/**
	 * 通道容器
	 */
	protected ProtocolTunnelContainer protocolTunnelContainer = ProtocolTunnelContainer.getInstance();
	/**
	 * 通道的状态
	 */
	private TunnelStatus tunnelStatus;

	/**
	 * 顶层的构造方法
	 *
	 * @param tunnelInfo 通道信息
	 */
	public BaseProtocolTunnel(T tunnelInfo) {
		this.tunnelInfo = tunnelInfo;
		this.tunnelType = tunnelInfo.getTunnelType();
		this.tunnelId = tunnelInfo.getId();
		this.log = TunnelLoggerFactory.getLogger(tunnelId, tunnelInfo.getTunnelName());
	}

	/**
	 * 开启通道通讯
	 *
	 * @return AbstractDataGather abstract data gather
	 * @throws DataExchangeException 抛出自定义的异常
	 */
	public abstract BaseProtocolTunnel startTunnel() throws DataExchangeException;

	/**
	 * 创建不同协议对应的通道
	 *
	 * @return AbstractDataGather abstract data gather
	 * @throws DataExchangeException 抛出自定义的异常
	 */
	public abstract BaseProtocolTunnel buildTunnel() throws DataExchangeException;


	/**
	 * 更新通道信息
	 *
	 * @param tunnelInfo 通道信息
	 * @return 实体本身
	 */
	public BaseProtocolTunnel refreshTunnelInfo(T tunnelInfo) {
		log.info("刷新{}的通道信息及点位", tunnelInfo.getTunnelName());
		this.tunnelInfo = tunnelInfo;
		this.setLog(TunnelLoggerFactory.getLogger(tunnelId, tunnelInfo.getTunnelName()));
		return this;
	}

	/**
	 * 解析采集数据点表
	 *
	 * @throws DataExchangeException 自定义异常
	 */
	public abstract void parseGatherDataPoint() throws DataExchangeException;


	/**
	 * 通道停止
	 * 停止 关闭通道
	 *
	 * @return {@link BaseProtocolTunnel}
	 * @throws DataExchangeException 数据交换异常
	 */
	public BaseProtocolTunnel tunnelStop() throws DataExchangeException {
		setTunnelStatus(TunnelStatus.ACTIVECLOSE);
		protocolTunnelContainer.stopUpdateTask(this.tunnelId);
		TunnelLoggerFactory.stop(log);
		return this;
	}


	public JSONObject getJSONObj() {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("tunnelId", this.tunnelId);
		jsonObject.put("tunnelName", this.tunnelInfo.getTunnelName());
		jsonObject.put("tunnelType", this.tunnelType);
		jsonObject.put("tunnelStatus", this.tunnelStatus);
		return jsonObject;
	}

}
